package org.pisces.wechat.filter;

import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import org.pisces.wechat.annotation.Anonymous;
import org.pisces.wechat.commons.WechatConstants;
import org.pisces.wechat.service.api.IUserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;

import com.alibaba.fastjson.JSONObject;

public class WechatAuthInterceptor extends HandlerInterceptorAdapter {
	@Autowired
	private IUserService userService;

	@Override
	public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
			throws Exception {

		HttpSession session = request.getSession();
		Object userSession = session.getAttribute("CURRENT_LOGIN_USER");
		boolean anonymous = false;
		if (handler instanceof HandlerMethod) {
			HandlerMethod method = (HandlerMethod) handler;
			anonymous = method.getMethod().isAnnotationPresent(Anonymous.class);
		}

		if (anonymous && !isWeiXin(request)) {
			return true;
		}

		if (userSession == null) {
			String uri = request.getRequestURI();
			Map<String, String[]> params = request.getParameterMap();
			if (!params.isEmpty()) {
				String formatUrl = formatUrl(params);
				System.out.println(formatUrl);
				uri += "?" + formatUrl;
			}

			if (request.getParameter("code") != null) {
				JSONObject result = userService.getAccessTokenByCode(request.getParameter("code"));
				if (result.containsKey("errcode")) {
					String redirect = encode(uri);
					response.sendRedirect(redirect);
					return false;
				} else {
					session.setAttribute("CURRENT_LOGIN_USER", result.getString("openid"));
					return true;
				}
			} else {
				System.out.println("重定向url" + uri);
				String redirect = encode(uri);
				response.sendRedirect(redirect);
				return false;
			}

		}
		return true;
	}

	private String encode(String url) {
		StringBuilder sb = new StringBuilder();
		try {
			String resultUrl = URLEncoder.encode("http://wechat.songxuan.org" + url, "utf-8");

			sb.append(WechatConstants.WECHAT_OPEN_URL).append("/connect/oauth2/authorize").append("?appid=")
					.append("wx66e4e106a9a621f8").append("&redirect_uri=").append(resultUrl)
					.append("&response_type=code&scope=snsapi_userinfo");
			return sb.toString();
		} catch (UnsupportedEncodingException e) {
			e.printStackTrace();
		}
		return sb.toString();
	}

	private boolean isWeiXin(HttpServletRequest request) {
		String userAgent = request.getHeader("user-agent").toLowerCase();
		return userAgent.indexOf("micromessenger") > -1;
	}

	private String formatUrl(Map<String, String[]> params) {
		StringBuilder build = new StringBuilder();
		List<String> keys = new ArrayList<String>(params.keySet());
		for (int i = 0; i < keys.size(); i++) {
			String key = keys.get(i);
			if (!"code".equals(key)||"state".equals(key)) {
				String value = params.get(key)[0];
				if (i == keys.size() - 1) {
					build.append(key).append("=").append(value);
				} else {
					build.append(key).append("=").append(value).append("&");
				}
			}

		}
		return build.toString();

	}

}
